package lvtu.opencv.worker;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import lvtu.opencv.bean.Pic;
import lvtu.opencv.db.DBUtil;
import lvtu.opencv.frontier.FaceFrontier;
import lvtu.opencv.frontier.NonFaceFrontier;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WorkController {

	private static final Logger logger = LoggerFactory.getLogger(WorkController.class
			.getName());

	/**
	 * Is the crawling of this session finished?
	 */
	protected boolean finished;

	/**
	 * Is the crawling session set to 'shutdown'. Crawler threads monitor this
	 * flag and when it is set they will no longer process new pages.
	 */
	protected boolean shuttingDown;

	protected lvtu.opencv.frontier.Frontier frontier;
	protected FaceFrontier faceFontier;
	protected NonFaceFrontier nonFaceFontier;

	protected ScheduledExecutorService pool = Executors
			.newScheduledThreadPool(10);

	/**
	 * Start the crawling session and wait for it to finish.
	 * 
	 * @param _c
	 *            the class that implements the logic for crawler threads
	 * @param numberOfCrawlers
	 *            the number of concurrent threads that will be contributing in
	 *            this crawling session.
	 */
	public <T extends Worker> void start(final Class<T> _c,
			final int numberOfCrawlers) {
		this.start(_c, numberOfCrawlers, true);
	}

	protected <T extends Worker> void start(final Class<T> _c,
			final int numberOfCrawlers, boolean isBlocking) {
		try {
			finished = false;
			//添加为处理的图片
			setPicToQueue();
			
			final List<Thread> threads = new ArrayList<Thread>();
			final List<T> crawlers = new ArrayList<T>();
			
			if(!finished)
				for (int i = 1; i <= numberOfCrawlers; i++) {
					T crawler = _c.newInstance();
					Thread thread = new Thread(crawler, "Crawler " + i);
					crawler.setThread(thread);
					crawler.init(i,this);
					pool.submit(thread);
					crawlers.add(crawler);
					threads.add(thread);
					logger.info("Crawler " + i + " started.");
				}
			
			
			Thread monitorThread = new Thread(new Runnable() {
				public void run() {
					try {
						while (!finished) {
							sleep(10);
							boolean someoneIsWorking = false;
							if (pool.isTerminated())
								System.out.println("pool is terminated");
							for (int i = 0; i < crawlers.size(); i++) {
								if (!crawlers.get(i).isWaiting()) {
									someoneIsWorking = true;
								}
							}
							if (!someoneIsWorking && frontier.size() == 0 ) {
								logger.info("It looks like no thread is working, waiting for 10 seconds to make sure...");
								//修改图片状态
								updatePicStatus();
								//添加为处理的图片
								setPicToQueue();
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
			monitorThread.start();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/***
	 * 向队列中 添加 pic 
	 */
	private void setPicToQueue(){
		List<Pic> list = DBUtil.getPic();
		if(list== null || list.size()==0){
			logger.info("所有图片都已经识别,程序结束!");
			pool.shutdown();
			finished = true;
		}else{
			frontier.put(list);
		}
	}
	
	/***
	 * 修改图片状态
	 */
	private void updatePicStatus(){
		ConcurrentLinkedQueue<Pic> q = faceFontier.getQueue();
		if(q!=null && q.size() > 0){
			DBUtil.updatePic(q, true);
			q.clear();
		}
		q =nonFaceFontier.getQueue();
		if(q!=null && q.size() > 0){
			DBUtil.updatePic(q, false);
			q.clear();
		}
	}
	
	protected void sleep(int seconds) {
		try {
			Thread.sleep(seconds * 1000);
		} catch (Exception ignored) {
		}
	}

	public boolean isShuttingDown() {
		return shuttingDown;
	}
	
	
	
}
